/**
 *
 * @author pquiring
 */

import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.Arrays;

public class NetApp extends javax.swing.JFrame {

  public static String version = "0.4";

  /**
   * Creates new form NetApp
   */
  public NetApp() {
    initComponents();
    setTitle("Net Tools/" + version);
    centerWindow(this);
    latency = new int[latencyLabel.getWidth()];
  }

  /**
   * This method is called from within the constructor to initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is always
   * regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    jTabbedPane1 = new javax.swing.JTabbedPane();
    clientTab = new javax.swing.JPanel();
    jPanel8 = new javax.swing.JPanel();
    jLabel4 = new javax.swing.JLabel();
    jLabel3 = new javax.swing.JLabel();
    jLabel2 = new javax.swing.JLabel();
    clientPort = new javax.swing.JTextField();
    clientMode = new javax.swing.JComboBox();
    clientHost = new javax.swing.JTextField();
    jPanel9 = new javax.swing.JPanel();
    clientStatus = new javax.swing.JLabel();
    clientStart = new javax.swing.JButton();
    jLabel5 = new javax.swing.JLabel();
    upSpeed = new javax.swing.JTextField();
    jLabel6 = new javax.swing.JLabel();
    downSpeed = new javax.swing.JTextField();
    jPanel10 = new javax.swing.JPanel();
    latencyLabel = new javax.swing.JLabel() {
      public void paintComponent(Graphics g) {
        paintLatency(g);
      }
    };
    clientStart2 = new javax.swing.JButton();
    clientStatus2 = new javax.swing.JLabel();
    jLabel15 = new javax.swing.JLabel();
    latencyMaxEver = new javax.swing.JTextField();
    jLabel16 = new javax.swing.JLabel();
    latencyMaxWindow = new javax.swing.JTextField();
    jPanel7 = new javax.swing.JPanel();
    serverStatus = new javax.swing.JLabel();
    serverPort = new javax.swing.JTextField();
    serverStart = new javax.swing.JButton();
    jLabel1 = new javax.swing.JLabel();
    toolsTab = new javax.swing.JPanel();
    jPanel5 = new javax.swing.JPanel();
    jLabel8 = new javax.swing.JLabel();
    pingHost = new javax.swing.JTextField();
    pingStart = new javax.swing.JButton();
    pingStatus = new javax.swing.JLabel();
    jPanel6 = new javax.swing.JPanel();
    jLabel7 = new javax.swing.JLabel();
    dnsHost = new javax.swing.JTextField();
    jLabel9 = new javax.swing.JLabel();
    dnsResolve = new javax.swing.JButton();
    dnsStatus = new javax.swing.JLabel();
    jLabel11 = new javax.swing.JLabel();
    dnsServer = new javax.swing.JTextField();
    jScrollPane1 = new javax.swing.JScrollPane();
    dnsIP = new javax.swing.JTextArea();
    dnsType = new javax.swing.JComboBox();
    jLabel12 = new javax.swing.JLabel();
    jPanel3 = new javax.swing.JPanel();
    checkipStart = new javax.swing.JButton();
    jLabel13 = new javax.swing.JLabel();
    jLabel14 = new javax.swing.JLabel();
    internetIP = new javax.swing.JTextField();
    intranetIP = new javax.swing.JTextField();
    ipStatus = new javax.swing.JLabel();
    jPanel1 = new javax.swing.JPanel();
    jPanel2 = new javax.swing.JPanel();
    jLabel10 = new javax.swing.JLabel();
    fileFile = new javax.swing.JTextField();
    fileSelect = new javax.swing.JButton();
    fileStatus = new javax.swing.JLabel();
    fileStart = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setTitle("Net Tools");
    setResizable(false);

    jPanel8.setBorder(javax.swing.BorderFactory.createTitledBorder("Client"));

    jLabel4.setText("Mode");

    jLabel3.setText("Port");

    jLabel2.setText("Server");

    clientPort.setText("33000");

    clientMode.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Full Duplex", "Send Only", "Receive Only" }));

    clientHost.setText("127.0.0.1");

    jPanel9.setBorder(javax.swing.BorderFactory.createTitledBorder("Bandwidth Test"));

    clientStatus.setText("Idle");

    clientStart.setText("Start");
    clientStart.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        clientStartActionPerformed(evt);
      }
    });

    jLabel5.setText("Upload Speed");

    upSpeed.setEditable(false);

    jLabel6.setText("Download Speed");

    downSpeed.setEditable(false);

    javax.swing.GroupLayout jPanel9Layout = new javax.swing.GroupLayout(jPanel9);
    jPanel9.setLayout(jPanel9Layout);
    jPanel9Layout.setHorizontalGroup(
      jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel9Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(jPanel9Layout.createSequentialGroup()
            .addComponent(clientStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(clientStart))
          .addGroup(jPanel9Layout.createSequentialGroup()
            .addComponent(jLabel5)
            .addGap(31, 31, 31)
            .addComponent(upSpeed))
          .addGroup(jPanel9Layout.createSequentialGroup()
            .addComponent(jLabel6)
            .addGap(18, 18, 18)
            .addComponent(downSpeed, javax.swing.GroupLayout.DEFAULT_SIZE, 288, Short.MAX_VALUE)))
        .addContainerGap())
    );
    jPanel9Layout.setVerticalGroup(
      jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel9Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel5)
          .addComponent(upSpeed, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel6)
          .addComponent(downSpeed, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(jPanel9Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
          .addComponent(clientStatus)
          .addComponent(clientStart))
        .addContainerGap())
    );

    jPanel10.setBorder(javax.swing.BorderFactory.createTitledBorder("Latency Test"));

    latencyLabel.setBackground(new java.awt.Color(0, 0, 0));
    latencyLabel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

    clientStart2.setText("Start");
    clientStart2.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        clientStart2ActionPerformed(evt);
      }
    });

    clientStatus2.setText("Idle");

    jLabel15.setText("Max (us)");

    latencyMaxEver.setEditable(false);

    jLabel16.setText("Window Max (us)");

    latencyMaxWindow.setEditable(false);

    javax.swing.GroupLayout jPanel10Layout = new javax.swing.GroupLayout(jPanel10);
    jPanel10.setLayout(jPanel10Layout);
    jPanel10Layout.setHorizontalGroup(
      jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel10Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addComponent(latencyLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
          .addGroup(jPanel10Layout.createSequentialGroup()
            .addComponent(clientStatus2, javax.swing.GroupLayout.DEFAULT_SIZE, 325, Short.MAX_VALUE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(clientStart2))
          .addGroup(jPanel10Layout.createSequentialGroup()
            .addComponent(jLabel15)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(latencyMaxEver)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addComponent(jLabel16)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(latencyMaxWindow, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE)))
        .addContainerGap())
    );
    jPanel10Layout.setVerticalGroup(
      jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel10Layout.createSequentialGroup()
        .addContainerGap()
        .addComponent(latencyLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        .addGroup(jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(clientStatus2)
          .addComponent(clientStart2))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(jPanel10Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel15)
          .addComponent(latencyMaxEver, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jLabel16)
          .addComponent(latencyMaxWindow, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
    );

    javax.swing.GroupLayout jPanel8Layout = new javax.swing.GroupLayout(jPanel8);
    jPanel8.setLayout(jPanel8Layout);
    jPanel8Layout.setHorizontalGroup(
      jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel8Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(jPanel8Layout.createSequentialGroup()
            .addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addComponent(jLabel2)
              .addComponent(jLabel3))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addComponent(clientHost)
              .addGroup(jPanel8Layout.createSequentialGroup()
                .addComponent(clientPort, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel4)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(clientMode, javax.swing.GroupLayout.PREFERRED_SIZE, 152, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
          .addComponent(jPanel9, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
          .addComponent(jPanel10, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        .addContainerGap())
    );
    jPanel8Layout.setVerticalGroup(
      jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel8Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel2)
          .addComponent(clientHost, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(jPanel8Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel3)
          .addComponent(clientPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(clientMode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jLabel4))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jPanel9, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jPanel10, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );

    jPanel7.setBorder(javax.swing.BorderFactory.createTitledBorder("Server"));

    serverStatus.setText("Idle");

    serverPort.setText("33000");

    serverStart.setText("Start");
    serverStart.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        serverStartActionPerformed(evt);
      }
    });

    jLabel1.setText("Port");

    javax.swing.GroupLayout jPanel7Layout = new javax.swing.GroupLayout(jPanel7);
    jPanel7.setLayout(jPanel7Layout);
    jPanel7Layout.setHorizontalGroup(
      jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel7Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(jPanel7Layout.createSequentialGroup()
            .addComponent(jLabel1)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addComponent(serverPort, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(0, 0, Short.MAX_VALUE))
          .addGroup(jPanel7Layout.createSequentialGroup()
            .addComponent(serverStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(serverStart)))
        .addContainerGap())
    );
    jPanel7Layout.setVerticalGroup(
      jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel7Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel1)
          .addComponent(serverPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(serverStatus)
          .addComponent(serverStart))
        .addContainerGap())
    );

    javax.swing.GroupLayout clientTabLayout = new javax.swing.GroupLayout(clientTab);
    clientTab.setLayout(clientTabLayout);
    clientTabLayout.setHorizontalGroup(
      clientTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(clientTabLayout.createSequentialGroup()
        .addContainerGap()
        .addGroup(clientTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addComponent(jPanel8, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
          .addComponent(jPanel7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        .addContainerGap())
    );
    clientTabLayout.setVerticalGroup(
      clientTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, clientTabLayout.createSequentialGroup()
        .addContainerGap()
        .addComponent(jPanel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jPanel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );

    jTabbedPane1.addTab("Bandwidth", clientTab);

    jPanel5.setBorder(javax.swing.BorderFactory.createTitledBorder("Ping"));

    jLabel8.setText("Host");

    pingHost.setText("example.com");

    pingStart.setText("Start");
    pingStart.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        pingStartActionPerformed(evt);
      }
    });

    pingStatus.setText("Idle");

    javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
    jPanel5.setLayout(jPanel5Layout);
    jPanel5Layout.setHorizontalGroup(
      jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel5Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(jPanel5Layout.createSequentialGroup()
            .addComponent(jLabel8)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(pingHost))
          .addGroup(jPanel5Layout.createSequentialGroup()
            .addComponent(pingStatus, javax.swing.GroupLayout.DEFAULT_SIZE, 357, Short.MAX_VALUE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(pingStart)))
        .addContainerGap())
    );
    jPanel5Layout.setVerticalGroup(
      jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel5Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel8)
          .addComponent(pingHost, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(pingStart)
          .addComponent(pingStatus))
        .addContainerGap())
    );

    jPanel6.setBorder(javax.swing.BorderFactory.createTitledBorder("DNS"));

    jLabel7.setText("Host:");

    dnsHost.setText("example.com");

    jLabel9.setText("Result:");

    dnsResolve.setText("Resolve");
    dnsResolve.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        dnsResolveActionPerformed(evt);
      }
    });

    dnsStatus.setText("Idle");

    jLabel11.setText("Server:");

    dnsServer.setText("8.8.8.8");

    dnsIP.setEditable(false);
    dnsIP.setColumns(20);
    dnsIP.setRows(5);
    jScrollPane1.setViewportView(dnsIP);

    dnsType.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "A", "MX", "AAAA" }));

    jLabel12.setText("Type:");

    javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6);
    jPanel6.setLayout(jPanel6Layout);
    jPanel6Layout.setHorizontalGroup(
      jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel6Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(jPanel6Layout.createSequentialGroup()
            .addComponent(jLabel7)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(dnsHost)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jLabel12)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(dnsType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
          .addGroup(jPanel6Layout.createSequentialGroup()
            .addComponent(jLabel11)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(dnsServer))
          .addGroup(jPanel6Layout.createSequentialGroup()
            .addComponent(jLabel9)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jScrollPane1))
          .addGroup(jPanel6Layout.createSequentialGroup()
            .addComponent(dnsStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(dnsResolve)))
        .addContainerGap())
    );
    jPanel6Layout.setVerticalGroup(
      jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel6Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel7)
          .addComponent(dnsHost, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(dnsType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jLabel12))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel11)
          .addComponent(dnsServer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addComponent(jLabel9)
          .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(dnsStatus)
          .addComponent(dnsResolve))
        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );

    jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Detect IP"));

    checkipStart.setText("Start");
    checkipStart.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        checkipStartActionPerformed(evt);
      }
    });

    jLabel13.setText("Internet IP:");

    jLabel14.setText("Intranet IP:");

    internetIP.setEditable(false);

    intranetIP.setEditable(false);

    ipStatus.setText("Idle");

    javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
    jPanel3.setLayout(jPanel3Layout);
    jPanel3Layout.setHorizontalGroup(
      jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel3Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(jPanel3Layout.createSequentialGroup()
            .addComponent(ipStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(checkipStart))
          .addGroup(jPanel3Layout.createSequentialGroup()
            .addComponent(jLabel13)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(internetIP))
          .addGroup(jPanel3Layout.createSequentialGroup()
            .addComponent(jLabel14)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(intranetIP)))
        .addContainerGap())
    );
    jPanel3Layout.setVerticalGroup(
      jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel13)
          .addComponent(internetIP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel14)
          .addComponent(intranetIP, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(checkipStart)
          .addComponent(ipStatus))
        .addContainerGap())
    );

    javax.swing.GroupLayout toolsTabLayout = new javax.swing.GroupLayout(toolsTab);
    toolsTab.setLayout(toolsTabLayout);
    toolsTabLayout.setHorizontalGroup(
      toolsTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(toolsTabLayout.createSequentialGroup()
        .addContainerGap()
        .addGroup(toolsTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
          .addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
          .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        .addContainerGap())
    );
    toolsTabLayout.setVerticalGroup(
      toolsTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(toolsTabLayout.createSequentialGroup()
        .addContainerGap()
        .addComponent(jPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(100, Short.MAX_VALUE))
    );

    jTabbedPane1.addTab("Tools", toolsTab);

    jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("File Read Benchmark (SSD)"));

    jLabel10.setText("File:");

    fileSelect.setText("Select...");
    fileSelect.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        fileSelectActionPerformed(evt);
      }
    });

    fileStatus.setText("Idle");

    fileStart.setText("Start");
    fileStart.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        fileStartActionPerformed(evt);
      }
    });

    javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
    jPanel2.setLayout(jPanel2Layout);
    jPanel2Layout.setHorizontalGroup(
      jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel2Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(jPanel2Layout.createSequentialGroup()
            .addComponent(jLabel10)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(fileFile, javax.swing.GroupLayout.DEFAULT_SIZE, 315, Short.MAX_VALUE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(fileSelect))
          .addGroup(jPanel2Layout.createSequentialGroup()
            .addComponent(fileStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(fileStart)))
        .addContainerGap())
    );
    jPanel2Layout.setVerticalGroup(
      jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel2Layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel10)
          .addComponent(fileFile, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(fileSelect))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(fileStatus)
          .addComponent(fileStart))
        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
      jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel1Layout.createSequentialGroup()
        .addContainerGap()
        .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        .addContainerGap())
    );
    jPanel1Layout.setVerticalGroup(
      jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel1Layout.createSequentialGroup()
        .addContainerGap()
        .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(426, Short.MAX_VALUE))
    );

    jTabbedPane1.addTab("Misc", jPanel1);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 475, javax.swing.GroupLayout.PREFERRED_SIZE)
    );
    layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(jTabbedPane1)
    );

    pack();
  }// </editor-fold>//GEN-END:initComponents

  private void dnsResolveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dnsResolveActionPerformed
    if (dns == null) {
      dnsIP.setText("");
      dns = new DNS(this, dnsServer.getText(), dnsHost.getText(), (String)dnsType.getSelectedItem());
      dns.start();
      dnsResolve.setText("Stop");
    } else {
      dns.close();
      dns = null;
      dnsResolve.setText("Resolve");
    }
  }//GEN-LAST:event_dnsResolveActionPerformed

  private void pingStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pingStartActionPerformed
    if (ping == null) {
      ping = new Ping(this, pingHost.getText());
      ping.start();
      pingStart.setText("Stop");
    } else {
      ping.close();
      ping = null;
      pingStart.setText("Start");
    }
  }//GEN-LAST:event_pingStartActionPerformed

  private void serverStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_serverStartActionPerformed
    if (server == null) {
      serverStart.setText("Stop");
      serverPort.setEnabled(false);
      server = new Server(this, Integer.valueOf(serverPort.getText()));
      server.start();
    } else {
      server.close();
      server = null;
      serverStart.setText("Start");
      serverPort.setEnabled(true);
      serverStatus.setText("Idle");
    }
  }//GEN-LAST:event_serverStartActionPerformed

  private void clientStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clientStartActionPerformed
    startClientBandwidthTest();
  }//GEN-LAST:event_clientStartActionPerformed

  private void fileStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileStartActionPerformed
    if (fileTest == null) {
      fileTest = new FileTest(this, fileFile.getText());
      fileTest.start();
      fileStart.setText("Stop");
      fileFile.setEditable(false);
    } else {
      fileTest.close();
      fileTest = null;
      fileStart.setText("Start");
      fileFile.setEditable(true);
    }
  }//GEN-LAST:event_fileStartActionPerformed

  private void fileSelectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileSelectActionPerformed
    JFileChooser chooser = new JFileChooser();
    chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
    chooser.setMultiSelectionEnabled(false);
    chooser.setCurrentDirectory(new File(fileFile.getText()));
    if (chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) return;
    fileFile.setText(chooser.getSelectedFile().toString().replaceAll("\\\\", "/"));
  }//GEN-LAST:event_fileSelectActionPerformed

  private void checkipStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_checkipStartActionPerformed
    getIP();
  }//GEN-LAST:event_checkipStartActionPerformed

  private void clientStart2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clientStart2ActionPerformed
    startClientLatencyTest();
  }//GEN-LAST:event_clientStart2ActionPerformed

  /**
   * @param args the command line arguments
   */
  public static void main(String args[]) {
    boolean server = false;
    int port = 33000;
    if (args != null && args.length > 0) {
      for(int a=0;a<args.length;a++) {
        if (args[a].equals("-server")) {
          server = true;
        }
        else if (args[a].startsWith("-port=")) {
          port = Integer.valueOf(args[a].substring(6));
        }
      }
    }

    if (server) {
      new Server(null, port).start();
      return;
    }

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
      public void run() {
        new NetApp().setVisible(true);
      }
    });
  }

  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JButton checkipStart;
  private javax.swing.JTextField clientHost;
  private javax.swing.JComboBox clientMode;
  private javax.swing.JTextField clientPort;
  private javax.swing.JButton clientStart;
  private javax.swing.JButton clientStart2;
  private javax.swing.JLabel clientStatus;
  private javax.swing.JLabel clientStatus2;
  private javax.swing.JPanel clientTab;
  private javax.swing.JTextField dnsHost;
  private javax.swing.JTextArea dnsIP;
  private javax.swing.JButton dnsResolve;
  private javax.swing.JTextField dnsServer;
  private javax.swing.JLabel dnsStatus;
  private javax.swing.JComboBox dnsType;
  private javax.swing.JTextField downSpeed;
  private javax.swing.JTextField fileFile;
  private javax.swing.JButton fileSelect;
  private javax.swing.JButton fileStart;
  private javax.swing.JLabel fileStatus;
  private javax.swing.JTextField internetIP;
  private javax.swing.JTextField intranetIP;
  private javax.swing.JLabel ipStatus;
  private javax.swing.JLabel jLabel1;
  private javax.swing.JLabel jLabel10;
  private javax.swing.JLabel jLabel11;
  private javax.swing.JLabel jLabel12;
  private javax.swing.JLabel jLabel13;
  private javax.swing.JLabel jLabel14;
  private javax.swing.JLabel jLabel15;
  private javax.swing.JLabel jLabel16;
  private javax.swing.JLabel jLabel2;
  private javax.swing.JLabel jLabel3;
  private javax.swing.JLabel jLabel4;
  private javax.swing.JLabel jLabel5;
  private javax.swing.JLabel jLabel6;
  private javax.swing.JLabel jLabel7;
  private javax.swing.JLabel jLabel8;
  private javax.swing.JLabel jLabel9;
  private javax.swing.JPanel jPanel1;
  private javax.swing.JPanel jPanel10;
  private javax.swing.JPanel jPanel2;
  private javax.swing.JPanel jPanel3;
  private javax.swing.JPanel jPanel5;
  private javax.swing.JPanel jPanel6;
  private javax.swing.JPanel jPanel7;
  private javax.swing.JPanel jPanel8;
  private javax.swing.JPanel jPanel9;
  private javax.swing.JScrollPane jScrollPane1;
  private javax.swing.JTabbedPane jTabbedPane1;
  private javax.swing.JLabel latencyLabel;
  private javax.swing.JTextField latencyMaxEver;
  private javax.swing.JTextField latencyMaxWindow;
  private javax.swing.JTextField pingHost;
  private javax.swing.JButton pingStart;
  private javax.swing.JLabel pingStatus;
  private javax.swing.JTextField serverPort;
  private javax.swing.JButton serverStart;
  private javax.swing.JLabel serverStatus;
  private javax.swing.JPanel toolsTab;
  private javax.swing.JTextField upSpeed;
  // End of variables declaration//GEN-END:variables

  public Server server;
  public Client client;
  public Ping ping;
  public DNS dns;
  public FileTest fileTest;
  public int latency[];
  public char mode;
  public int maxEver, maxWindow;  //latency values

  private char getMode() {
    return ((String)clientMode.getSelectedItem()).charAt(0);
  }

  public void setServerStatus(String status) {
    serverStatus.setText(status);
  }

  public void setClientStatus(String status) {
    if (mode == 'L') {
      clientStatus2.setText(status);
    } else {
      clientStatus.setText(status);
    }
  }

  public void setReadSpeed(String spd) {
    downSpeed.setText(spd);
  }

  public void setWriteSpeed(String spd) {
    upSpeed.setText(spd);
  }

  public void setPingStatus(String status) {
    pingStatus.setText(status);
  }

  public void setDNSStatus(String status) {
    dnsStatus.setText(status);
  }

  public void setDNSIP(String status) {
    dnsIP.setText(status);
    dnsResolve.setText("Resolve");
    dnsStatus.setText("Idle");
    dns = null;
  }

  public void setFileStatus(String status) {
    fileStatus.setText(status);
  }

  public void fileTestComplete() {
    fileTest = null;
    fileStart.setText("Start");
    fileFile.setEditable(true);
  }

  private void getIP() {
    try {
      //detect internet ip
      BufferedReader reader = new BufferedReader(new InputStreamReader
        (new URL("http://checkip.dyndns.org").openStream()));
      String line = reader.readLine();
      int i1 = line.indexOf("Address: ");
      int i2 = line.indexOf("</body>");
      internetIP.setText(line.substring(i1+9, i2));
      //detect intranet ip
      Socket s = new Socket("checkip.dyndns.org", 80);
      String intra = s.getLocalAddress().getHostAddress();
      s.close();
      intranetIP.setText(intra);
    } catch (Exception e) {
      e.printStackTrace();
      ipStatus.setText(e.toString());
    }
  }

  private void startClientBandwidthTest() {
    if (client == null) {
      clientHost.setEnabled(false);
      clientPort.setEnabled(false);
      clientMode.setEnabled(false);
      clientStart.setText("Stop");
      clientStart2.setEnabled(false);
      mode = getMode();
      client = new Client(this, clientHost.getText(), Integer.valueOf(clientPort.getText()), mode);
      client.start();
    } else {
      client.close();
      client = null;
      clientStart.setText("Start");
      clientStart2.setEnabled(true);
      clientStatus.setText("Idle");
      clientHost.setEnabled(true);
      clientPort.setEnabled(true);
      clientMode.setEnabled(true);
    }
  }

  private void startClientLatencyTest() {
    if (client == null) {
      clientHost.setEnabled(false);
      clientPort.setEnabled(false);
      clientMode.setEnabled(false);
      clientStart2.setText("Stop");
      clientStart.setEnabled(false);
      mode = 'L';
      client = new Client(this, clientHost.getText(), Integer.valueOf(clientPort.getText()), mode);
      client.start();
      clearLatency();
    } else {
      client.close();
      client = null;
      clientStart2.setText("Start");
      clientStart.setEnabled(true);
      clientStatus2.setText("Idle");
      clientHost.setEnabled(true);
      clientPort.setEnabled(true);
      clientMode.setEnabled(true);
    }
  }

  /** Centers a window on screen (works with java.awt.Window/Frame javax.swing.JWindow/JFrame/JDialog */
  public static void centerWindow(java.awt.Window window) {
    Dimension d = window.getSize();
    Rectangle s = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
    window.setLocation(s.width/2 - d.width/2, s.height/2 - d.height/2);
  }

  private void clearLatency() {
    Arrays.fill(latency, 0);
    maxEver = 0;
    maxWindow = 0;
  }

  public void addLatency(int value) {
    for(int a=1;a<latency.length;a++) {
      latency[a-1] = latency[a];
    }
    latency[latency.length - 1] = value;
    latencyLabel.repaint();
  }

  public void paintLatency(Graphics g) {
    int w = latency.length;
    int h = latencyLabel.getHeight();
    int max = 1;
    for(int a=0;a<w;a++) {
      if (latency[a] > max) {
        max = latency[a];
      }
    }
    if (max > maxEver) {
      maxEver = max;
      latencyMaxEver.setText(Integer.toString(maxEver));
//      latencyMaxEver.repaint();
    }
    if (max != maxWindow) {
      maxWindow = max;
      latencyMaxWindow.setText(Integer.toString(maxWindow));
//      latencyMaxWindow.repaint();
    }
    g.setColor(Color.black);
    g.fillRect(0, 0, w, h);
    g.setColor(Color.green);
    for(int x=0;x<w;x++) {
      int y = h - (latency[x] * 100 / max);
      if (y >= h) y = h-1;
      if (y < 0) y = 0;
      g.drawLine(x, y, x, h-1);
    }
  }
}
